package com.example.internetplus.accelerationService.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.aliyun.oss.AliyunUtils;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.internetplus.accelerationService.UserService;
import com.example.internetplus.config.properties.JwtProperties;
import com.example.internetplus.domain.dto.LoginFormatDto;
import com.example.internetplus.domain.enums.JobEnum;
import com.example.internetplus.domain.query.Userquery;
import com.example.internetplus.domain.vo.UserVO;
import com.example.internetplus.controller.globalException.exception.BusinessException;
import com.example.internetplus.controller.globalException.exception.SystemException;
import com.example.internetplus.mapper.UserMapper;
import com.example.internetplus.domain.po.User;
import com.example.internetplus.result.Result;
import com.example.internetplus.utils.JwtUtils;
import com.example.internetplus.utils.RedisUtil;
import com.example.internetplus.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;

import static com.example.internetplus.constrants.ExceptionConstants.*;
import static com.example.internetplus.constrants.RedisConstants.queryDoctorBefore;
import static com.example.internetplus.constrants.RedisConstants.queryPatientBefore;
import static com.example.internetplus.constrants.ResultConstrants.*;

@Slf4j
@RequiredArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final JwtUtils jwtUtils;

    private final JwtProperties jwtProperties;

    private final RedisUtil redisUtil;

    private final UserMapper userMapper;

    private final AliyunUtils aliyunUtils;
    public Result loginCheck(LoginFormatDto loginFormatDto){
       String userName = loginFormatDto.getUserName();
       User user = lambdaQuery().eq(userName != null,User::getUserName, userName).one();
       if(user == null){
           return Result.defeat("您还没有注册过，请先注册",BUISNEES_FIND_NULL);
       }
       if (!user.getPassword().equals(loginFormatDto.getPassword())){
           return Result.defeat("密码错误",BUISNESS_LOGIN_PWD,userName);
       }
       //发送jwt令牌
        String token = jwtUtils.createToken(user.getId(), jwtProperties.getTokenTTL());
        long seconds = jwtProperties.getTokenTTL().toSeconds();
        redisUtil.cacheValue("token",token, seconds + 3600l);
        //将user转换成userVO
       UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
       userVO.setToken(token);
       return Result.success("登录成功",loginSuccess,userVO);
   }

    @Override
    public Result queryUser(Userquery userquery) {
        String userName = userquery.getUserName();
        JobEnum job = userquery.getJob();
        List<User> userList = query().eq(userName != null, "user_name", userName)
                .eq(job != null, "job", job)
                .list();
        List<UserVO> userVOS = BeanUtil.copyToList(userList, UserVO.class);
        return Result.success("success",successFind,userVOS);
    }

    @Override
    public Result queryDoctor(Userquery userquery) {
        //在redis之中查询医生
        List<User> doctorList = redisUtil.getSet("user:doctor" + userquery.getUserName(),User.class);
        //如果没有就去数据库之中查
        User user = null;
        List<Long> ids = null;
        try {
            if(CollUtil.isEmpty(doctorList)){
                user = query().eq(userquery != null, "userName", userquery.getUserName()).one();
                ids = userMapper.queryDoctorById(user.getId());
                doctorList = query().in(ids != null, "id", ids).list();
            }
        }catch (Exception e){
            throw new SystemException("服务器异常，请稍后再试",SYSTEM_TIMEOUT_ERROR);
        }
        //写入redis;
        redisUtil.addSet(queryDoctorBefore + user.getUserName(),ids);
        return Result.success("成功找到医生",successFind,doctorList);
    }

    @Override
    public Result queryPatient(Userquery userquery) {
        //在redis之中查询医生
        List<User> patientList = redisUtil.getSet(queryPatientBefore + userquery.getUserName(),User.class);
        User user = null;
        List<Long> ids = null;
        //如果没有就去数据库之中查
        try {
            if (CollUtil.isEmpty(patientList)) {
                user = query().eq(userquery != null, "userName", userquery.getUserName()).one();
                ids = userMapper.queryDoctorById(user.getId());
                patientList = query().in(ids != null, "id", ids).list();
            }
        }catch (Exception e){
            throw new SystemException("服务器超时，请稍后再试",e,SYSTEM_TIMEOUT_ERROR);
        }
        //写入redis;
        redisUtil.addSet(queryPatientBefore + user.getUserName(),ids);
        return Result.success("成功找到患者",successFind,patientList);
    }

    @Override
    public Result insertUser(LoginFormatDto userDto) {
        User user = BeanUtil.copyProperties(userDto, User.class);
        //默认为患者
        try {
            user.setJob(JobEnum.patient);
        }catch (Exception e){
            throw new SystemException("服务器超时，请稍后再试",e,SYSTEM_TIMEOUT_ERROR);
        }
        boolean save = save(user);
        if(save == false){
            throw new BusinessException("注册，请稍后再试",SYSTEM_REG_SAVE);
        }
        return Result.success("注册成功",registerSuccess);
    }

    @Override
    public Result setImage(MultipartFile multipartFile) {
        String image = null;
        try {
            image = aliyunUtils.storeFile(multipartFile);
        } catch (ClientException e) {
            throw new SystemException("阿里云停止服务",10503);
        } catch (IOException e) {
            throw new SystemException("上传失败",10503);
        }
        Long userId = UserContext.getUser();
        boolean b = update().eq(userId != null, "id", userId).set("image",image).update();
        if (!b){
            throw new SystemException("更新失败",10503);
        }
        return Result.success("上传成功",200,image);
    }

    @Override
    public String queryUserNameById(Long id) {
        String userName = userMapper.queryUserNameById(id);
        return userName;
    }
}
